package com.hcss.common.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * MapList维护了一个key对一个列表的映射关系，每次放入一个键值对时， 会将值放在该键对应的列表中，如果列表不存在则创建
 * 
 * @param <K>
 * @param <V>
 */
public class MapList<K, V> {
	private final HashMap<K, List<V>> map = new HashMap<K, List<V>>();

	public MapList() {
		super();
	}

	/** 加入一个键值对 */
	public void put(K key, V value) {
		List<V> l = map.get(key);
		if (l == null) {
			l = new LinkedList<V>();
		}
		l.add(value);
		map.put(key, l);
	}

	/** 移除一个键值对 */
	public boolean remove(K key, V value) {
		List<V> l = map.get(key);
		if (l == null) {
			return false;
		}
		boolean b = l.remove(value);
		if (l.size() == 0) {
			map.remove(key);
		}
		return b;
	}

	/** 移除键对应的值列表 */
	public List<V> remove(K key) {
		List<V> l = map.get(key);
		if (l == null) {
			return null;
		}
		map.remove(key);
		return l;
	}

	/** 得到键对应的值列表，为空时返回null */
	public List<V> get(K key) {
		return map.get(key);
	}

	/** 得到维护键与值列表之间关系的HashMap */
	public HashMap<K, List<V>> toMap() {
		return map;
	}

	/** 得到键的集合 */
	public Set<K> keySet() {
		return map.keySet();
	}

	/** 得到所有值的集合 */
	public Set<V> valueSet() {
		Set<V> s = new HashSet<V>();
		Iterator<List<V>> it = map.values().iterator();
		while (it.hasNext()) {
			List<V> l = it.next();
			if (l == null) {
				continue;
			}
			s.addAll(l);
		}
		return s;
	}

	/** 得到所有值的集合(不唯一) */
	public List<V> valueList() {
		List<V> l = new ArrayList<V>();
		Iterator<List<V>> it = map.values().iterator();
		while (it.hasNext()) {
			List<V> t = it.next();
			if (t == null) {
				continue;
			}
			l.addAll(t);
		}
		return l;
	}

	/** 返回键的数量 */
	public int size() {
		return map.size();
	}

	/** 清除所有数据 */
	public void clear() {
		map.clear();
	}

	/** 是否包含键 */
	public boolean containsKey(K key) {
		return map.containsKey(key);
	}

	@Override
	public String toString() {
		return map.toString();
	}

	/** 是否为空 */
	public boolean isEmpty() {
		// remove方法保证了值列表为空时删除key
		return map.isEmpty();
	}

	/** 是否包含值 */
	public boolean containsValue(V value) {
		Iterator<List<V>> it = map.values().iterator();
		while (it.hasNext()) {
			List<V> l = it.next();
			if (l == null) {
				continue;
			}
			if (l.contains(value)) {
				return true;
			}
		}
		return false;
	}

	/** 全部加入 */
	public void putAll(MapList<K, V> ml) {
		if (ml == null) {
			return;
		}
		Iterator<K> it = ml.keySet().iterator();
		while (it.hasNext()) {
			K key = it.next();
			List<V> l = map.get(key);
			List<V> nl = ml.get(key);
			if (nl != null) {// 不需判断nl.size()!=0,因为MapList的put的remove逻辑保证了
				if (l == null) {
					l = new LinkedList<V>();
					map.put(key, l);
				}
				l.addAll(nl);
			}
		}
	}

	/** 全部加入 */
	public void putAll(Map<K, V> m) {
		if (m == null) {
			return;
		}
		Iterator<K> it = m.keySet().iterator();
		while (it.hasNext()) {
			this.put(it.next(), m.get(it.next()));
		}
	}
}
